/*
* ////////////////////////////////////////////////
*
* 开发者：AZPEP
* 友情链接：
*	-	B站：		零分的考卷			https://space.bilibili.com/257391258
*	-	Github：	AZPEP-BiliBili		https://github.com/AZPEP-BiliBili
*	-	Gitee：		AZPEP_BiliBili		https://gitee.com/AZPEP_BiliBili
*
* CopyRight AZPEP
*
* ////////////////////////////////////////////////
*/

#include <iostream>
#include "pch.h"
#include <filesystem>
#include "GetStr.h"
#include "Struct.h"
#include "WriteLog.h"
#include <direct.h>
#include "Struct.h"
#include "WriteLog.h"
#include <fstream>
#include <comutil.h>
bool dirExists(const std::string& dir);

/// <summary>
/// 启动日志服务，可自由指定日志路径
/// </summary>
/// <param name="Title">日志标题</param>
/// <param name="LogFilePath">日志文件路径</param>
/// <param name="PrintToConsole">打印日志到控制台，默认开启</param>
/// <param name="CallBackFunction">回传函数，为NULL为不启用</param>
/// <returns>成功返回句柄，失败返回0，可用GetLastError()获取错误信息</returns>
ASTLOG_HANDLE AstLog_StartServiceExW2(
	std::wstring Title,
	std::wstring LogFilePath,
	bool PrintToConsole,
	AstLogCallBackFuncW CallBackFunction
);

/// <summary>
/// 启动日志服务
/// </summary>
/// <param name="Title">日志标题</param>
/// <param name="PrintToConsole">打印日志到控制台，默认开启</param>
/// <returns>成功返回句柄，失败返回0，可用GetLastError()获取错误信息</returns>
EXTERN_C ASTLOG_HANDLE AstLog_StartServiceW(
	std::wstring Title,
	bool PrintToConsole,
	AstLogCallBackFuncW CallBackFunction
) {
	try {
		//获取程序运行路径
		//获取程序运行路径
		wchar_t WorkDirChar[512];
		_wgetcwd(WorkDirChar, 512);

		std::wstringstream LogFileFolder;  //日志文件夹路径
		LogFileFolder << WorkDirChar << L"\\Log";

		//检查日志文件夹是否存在
		if (!dirExists(".\\Log")) {
			//没有，创建目录
			bool Statuc = CreateDirectory(LogFileFolder.str().c_str(), NULL);
		}

		//std::wstringstream LogFilePath;     //日志路径
		//LogFilePath << LogFileFolder.str() << L"\\log-" << LogGetDateStringPath() << L".log";

		//free(WorkDirChar);

		//不知道怎么回事，Release版本使用wstringstream会报错
		std::wstring LogFilePathWstr = std::format(L"{}\\log-{}.log", LogFileFolder.str(), LogGetDateStringPath());

		//开始创建日志
		return AstLog_StartServiceExW2(
			Title,
			LogFilePathWstr,
			PrintToConsole,
			CallBackFunction
		);
	}
	catch (...) {
		//捕获到异常，返回false
		return false;
	}
}

/// <summary>
/// 启动日志服务，可自由指定日志路径
/// </summary>
/// <param name="Title">日志标题</param>
/// <param name="LogFilePath">日志文件路径</param>
/// <param name="PrintToConsole">打印日志到控制台，默认开启</param>
/// <param name="CallBackFunction">回传函数，为NULL为不启用</param>
/// <returns>成功返回句柄，失败返回0，可用GetLastError()获取错误信息</returns>
ASTLOG_HANDLE AstLog_StartServiceExW(
	std::wstring Title,
	std::wstring LogFilePath,
	bool PrintToConsole,
	AstLogCallBackFuncW CallBackFunction
) {
	return AstLog_StartServiceExW2(
		Title,
		LogFilePath,
		PrintToConsole,
		CallBackFunction
	);
}

/// <summary>
/// 启动日志服务，可自由指定日志路径
/// </summary>
/// <param name="Title">日志标题</param>
/// <param name="LogFilePath">日志文件路径</param>
/// <param name="PrintToConsole">打印日志到控制台，默认开启</param>
/// <param name="CallBackFunction">回传函数，为NULL为不启用</param>
/// <returns>成功返回句柄，失败返回0，可用GetLastError()获取错误信息</returns>
ASTLOG_HANDLE AstLog_StartServiceExW2(
	std::wstring Title,
	std::wstring LogFilePath,
	bool PrintToConsole,
	AstLogCallBackFuncW CallBackFunction
) {
	try {
		// 创建log文件
		/*
		std::ofstream f(LogFilePath.c_str(),ios::out);
		f.write("\0", 1);
		f.close();
		*/
		FILE* o_file = _wfopen(LogFilePath.c_str(), L"w+");
		fwprintf(o_file, L"\"LogModule.dll\" Create This File\n\n");
		fclose(o_file);

		//添加结构体
		ASTLOG_HANDLE Handle = AppendStruct(
			LogFilePath,
			PrintToConsole,
			CallBackFunction
		);

		//检查是否开启
		if (AstLog_CheckHandleAvaiable(Handle) != 0) {
			//未开启，报错返回
			return 0;
		}

		// 开始输出信息
		AstLog_WriteLogW(
			Handle,
			L"========== AZPEP SysRi Tool 日志记录程序 =========="
		);
		AstLog_WriteLogW(
			Handle,
			L"版本：2.0.0.0"
		);
#ifdef _M_ARM64
		AstLog_WriteLogW(
			Handle,
			L"程序运行平台：ARM64"
		);
#elif _M_X64
		AstLog_WriteLogW(
			Handle,
			L"程序运行平台：x64"
		);
#else
#error 请添加架构
#endif
		AstLog_WriteLogW(
			Handle,
			L"开发者： AZPEP"
		);
		AstLog_WriteLogW(
			Handle,
			L"CopyRight 2024 AZPEP"
		);
		AstLog_WriteLogW(
			Handle,
			L"--------------------"
		);
		AstLog_WriteLogW(
			Handle,
			L"开发者主页："
		);
		AstLog_WriteLogW(
			Handle,
			L"- B站：零分的考卷 https://space.bilibili.com/257391258"
		);
		AstLog_WriteLogW(
			Handle,
			L"- Github：AZPEP-BiliBili https://github.com/AZPEP-BiliBili"
		);
		AstLog_WriteLogW(
			Handle,
			L"- Gitee：AZPEP_BiliBili https://gitee.com/AZPEP_BiliBili"
		);
		AstLog_WriteLogW(
			Handle,
			L"--------------------"
		);
		AstLog_WriteLogW(
			Handle,
			std::format(L"输出到文件：{}", ((LogFilePath != L"") ? L"是" : L"否"))
		);
		AstLog_WriteLogW(
			Handle,
			std::format(L"日志文件路径：{}", LogFilePath)
		);
		AstLog_WriteLogW(
			Handle,
			std::format(L"启用日志输出：{}", PrintToConsole)
		);
		AstLog_WriteLogW(
			Handle,
			std::format(L"启动程序内回传：{}", ((LogFilePath != L"") ? L"是" : L"否"))
		);
		AstLog_WriteLogW(
			Handle,
			L"===================="
		);
		AstLog_WriteLogW(
			Handle,
			L"日志服务已启用！"
		);

		//开启成功，返回句柄
		return Handle;
	}
	catch (...) {
		// 抛出异常，返回0
		return 0;
	}

}

/// <summary>
/// 停止日志服务
/// </summary>
/// <param name="Handle">日志句柄</param>
/// <returns>成功返回true，失败返回false</returns>
EXTERN_C bool AstLog_StopService(
	ASTLOG_HANDLE Handle
) {
	//检查是否开启
	if (AstLog_CheckHandleAvaiable(Handle) == -1) {
		//未开启，报错返回
		return false;
	}
	AstLog_WriteLogW(Handle, L"日志服务程序性中止！");
	AstLog_WriteLogW(Handle, L"++++++++++++++++++++");
	return DeleteStructByHandle(Handle);
}

// 检查目录是否存在
bool dirExists(const std::string& dir)
{
	DWORD attribs = ::GetFileAttributesA(dir.c_str());
	if (attribs == INVALID_FILE_ATTRIBUTES)
	{
		return false;
	}
	return (attribs & FILE_ATTRIBUTE_DIRECTORY);
}
